package com.turbo.cloud.core.annotations.dict.processor;


import cn.hutool.core.util.ReflectUtil;
import cn.hutool.extra.spring.SpringUtil;
import com.turbo.cloud.core.annotations.dict.annotations.DictTranslate;
import com.turbo.cloud.core.annotations.dict.bean.BeanDescription;
import com.turbo.cloud.core.annotations.dict.handler.DefaultTranslateTypeHandler;
import com.turbo.cloud.core.annotations.dict.handler.TranslateUnpackingHandler;
import com.turbo.cloud.core.annotations.dict.translator.Translator;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

import java.lang.reflect.Field;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
 * 词典转义执行类
 *
 * @author zhangluning
 */
@Slf4j
public class TranslateProcessor {

    /**
     * @param obj       原数据
     * @param beanClass 原数据实体
     * @param field     词典转义字段
     */
    public static void process(Object obj, Class<?> beanClass, String field) {
        Object targetObj = ReflectUtil.getFieldValue(obj, field);
        TranslateUnpackingHandler listTypeHandler = new DefaultTranslateTypeHandler();
        int unpackingType = listTypeHandler.unpackingType(targetObj);
        if (unpackingType > 0) {
            List<BeanDescription> unpacking = null;
            switch (unpackingType) {
                case 1:
                    unpacking = listTypeHandler.unpackingCollection((Collection) targetObj, beanClass);
                    break;
                case 2:
                    unpacking = listTypeHandler.unpackingMap((Map) targetObj, beanClass);
                    break;
                case 3:
                    unpacking = listTypeHandler.unpackingArray((Object[]) targetObj, beanClass);
                    break;
                case 4:
                    unpacking = listTypeHandler.unpackingOther(targetObj, beanClass);
                    break;
                default:
                    throw new RuntimeException("暂不支持的解包类型");
            }
            process(unpacking);
        }
    }

    /**
     * @param unpackingList 拆包数据
     */
    public static void process(List<BeanDescription> unpackingList) {
        if (CollectionUtils.isEmpty(unpackingList)) {
            return;
        }
        for (BeanDescription beanDescription : unpackingList) {
            // 优先从指定的实体类获取字段属性
            Class<?> beanClass = beanDescription.getClazz();
            Field[] fields = beanClass.getDeclaredFields();
            // 如果未指定实体类，从当前数据
            if (fields.length == 0) {
                Object obj = beanDescription.getBean();
                fields = obj.getClass().getDeclaredFields();
            }

            for (Field field : fields) {
                DictTranslate dictTranslate = field.getAnnotation(DictTranslate.class);
                if (Objects.nonNull(dictTranslate)) {
                    Object obj = beanDescription.getBean();
                    Object translationFieldValue = ReflectUtil.getFieldValue(obj, dictTranslate.translationField());

                    try {
                        // 设置可访问权限
                        field.setAccessible(true);
                        Class<? extends Translator> translatorClass = dictTranslate.translator();

                        // 调用翻译方法
                        Translator translator;
                        if (translatorClass.isAnnotationPresent(Component.class)) {
                            // 实现类上配置了@Component则使用Spring容器获取
                            translator = SpringUtil.getBean(translatorClass);
                            String dictName = translator.translate(String.valueOf(translationFieldValue));
                            field.set(obj, dictName);
                        } else {
                            field.set(obj, "请在DictTranslate指定Translator配置");
                        }
                    } catch (IllegalAccessException e) {
                        throw new RuntimeException(e);
                    }
                }
            }
        }
    }
}
